home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 4
/
Apprentice-Release4.iso
/
Languages
/
Mops 2.7
/
Mops ƒ
/
Args
next >
Wrap
Text File
|
1995-11-17
|
7KB
|
282 lines
\ Support for named parms and local variables
cr .( loading Args...)
24 constant MAXPL \ Should be enough!!
false value LOCFLG \ true = looking for local var tokens
create PARMLIST maxPL cells reserve
0 value SVHASH
false value FLOAT?
0 value PLentry_addr
: INITLOCS \ Initializes flags etc.
0 -> #PL 0 -> #P 0 -> #F
0 -> FltFlg false -> locFlg ;
: FINDINPARMLIST \ ( addr -- loc# T OR -- F )
\ loc# counts from right to left in the local/parm list.
dup 1+ c@ & % = -> float?
hash -> svHash false
#PL 0exit
ParmList #PL 4* bounds DO
svHash i @ =
IF ( found )
drop #PL
i parmlist - 4/
- 1- true LEAVE
THEN
4 +LOOP ;
: ADDTOPARMLIST \ ( addr -- ) Adds an element to ParmList.
\ addr points to a counted string.
findinParmList ?error 95 \ Name not unique
#PL maxPL >= ?error 110
FltFlg 1 << float? if 1 or 1 ++> #F then -> FltFlg
svHash
#PL 1 ++> #PL 4* ParmList + ! ;
: FIRSTCHR
here 1+ c@ ;
:f {
local? IF \ local? already non-zero - this ought to mean we're
\ in a local section
local? 0< ?error 92 -1 -> local?
THEN
initLocs
BEGIN \ Loop to add parms/locals to parmlist
Mword drop
firstChr & - <> \ look for --
WHILE
firstChr dup & \ = swap & / = or
\ Note: we allow / as an alternative to \
IF true -> locFlg
ELSE firstChr & } = ?error 111
locFlg nif 1 ++> #P then
here AddToParmList
THEN
REPEAT
local? NIF \ In local sections, we do this at :LOC
here -> PLentry_addr
\ If we have temp objects, we'll have to backup the DP and
\ recompile the entry sequence, since there'll be an extra local
\ (the frame pointer)
PLentry
THEN
& } parse 2drop \ eat characters until }
rest nip 0< ?error 112 ;f \ Err if no final }
\ FIND will call Pfind to attempt to find a name first.
\ If Pfind finds the name is a local, it returns true and the
\ cfa of LocParm, which is a dummy word whose handler compiles
\ a local reference.
: PFIND \ ( str-addr -- cfa T | -- str-addr F )
state
NIF false
ELSE dup FindInParmList
IF \ Found
-> loc# drop
float? IF ['] FlocParm ELSE ['] locParm THEN
true
ELSE false \ Not found
THEN
THEN ;
: ,EXEC \ ( cfa n -- )
state
IF (compN) ELSE exN THEN ;
\ Here are the different types that we can put prefixes on or send
\ messages to:
TYPE{ notfnd locTyp flocTyp
tmpObjTyp objTyp ivarTyp classTyp superTyp
valTyp fvalTyp vecTyp dynVecTyp objptrTyp
regTyp lbTyp lbSelfTyp bktTyp wordTyp }
\ notFnd - not previously defined
\ locTyp - a local or named parm
\ tmpObjTyp - a temporary (local) object
\ objTyp - an object
\ ivarTyp - an ivar
\ classTyp - a class
\ superTyp - a named superclass specified by msg: super> someClass
\ valTyp - a value
\ FvalTyp - a floating point value
\ vecTyp - a vector
\ dynVecTyp - a dynamic vector
\ regTyp - a 680x0 register
\ lbTyp - ** or [] meaning late bind
\ lbSelfTyp - [self] meaning late bind to self
\ BktTyp - [ - Neon-compatible late bind
\ wordTyp - a word
\ PRFTOKEN returns the type of a token for a prefix op.
\ First we need to make some handler codes available above the Nucleus.
: HDLR \ ( cfa -- ha )
2- w@x ;
' key hdlr constant VECTCODE
' base hdlr constant VALCODE
' ^base hdlr constant REGCODE
' hdlr hdlr constant WORDCODE
objPtr XX ' xx hdlr forget xx
constant OBJPTRCODE
dynamicVect XX ' xx hdlr forget xx
constant DYNVECTCODE
: PRFTOKEN \ ( -- cfa type )
' dup ['] locParm = IF locTyp EXIT THEN
dup ['] FlocParm = IF FlocTyp EXIT THEN
dup hdlr
CASE
valCode OF valTyp ENDOF
FvalCode OF FvalTyp ENDOF
vectCode OF vecTyp ENDOF
dynVectCode OF dynVecTyp ENDOF
regCode OF regTyp ENDOF
objPtrCode OF objPtrTyp ENDOF
114 die
ENDCASE ;
forward ToObjPtr \ Stores to an objPtr. Defined in file Class.
: -> immediate
PrfToken \ All types are legal
objPtrTyp = IF toObjPtr EXIT THEN
$ 60 ( opcode for Store ) ,exec ;
\ NOTE: opcode for store hard coded here!!!
: CvrtFcode \ ( code -- code' )
CASE
$ 21 OF $ 41 ENDOF \ +
$ 22 OF $ 48 ENDOF \ -
$ 28 OF $ 55 ENDOF \ Neg
?error 114
ENDCASE ;
: (+->) \ ( code -- cfa code' )
PrfToken ( code cfa type ) rot swap ( cfa code type )
CASE
locTyp OF ENDOF
FlocTyp OF cvrtFcode ENDOF
valTyp OF ENDOF
FvalTyp OF cvrtFcode ENDOF
regTyp OF ENDOF
?error 114
ENDCASE ;
: (FOP)
PrfToken rot swap
CASE
locTyp OF ENDOF
FlocTyp OF ENDOF
FvalTyp OF ENDOF
?error 114
ENDCASE ;
\ Note: the following opcodes have to agree with the definitions in
\ OD.asm. I could have defined them as constants but this would have
\ used up dictionary space for no great benefit.
: ++> $ 21 (+->) ,exec ; immediate
: +> postpone ++> ; immediate \ A synonym.
: --> $ 22 (+->) ,exec ; immediate
: AND> $ 23 (+->) ,exec ; immediate
: OR> $ 24 (+->) ,exec ; immediate
: XOR> $ 25 (+->) ,exec ; immediate
: NEG> $ 28 (+->) ,exec ; immediate
: NOT> $ 29 (+->) ,exec ; immediate
: *> $ 42 (fop) ,exec ; immediate
: /> $ 49 (fop) ,exec ; immediate
: ABS> $ 54 (fop) ,exec ; immediate
' Pfind -> Ufind
\ =========== Local sections ===========
forward INITTEMPS
: ?LOC local? 0= ?error 91 ; \ "We're not in a local section"
: LOCAL
local? ?error 93 1 -> local? \ We change it to the normal -1
\ as soon as "{" is read.
forward ;
: :LOC immediate
local? 1 = IF msg# 96 THEN \ warning - no locals defined
?loc 304
here ' (patch) :noname \ Like :F
#PL IF PLentry THEN
frameSize IF initTemps THEN
false -> local? \ We do this here so any EXITs
; \ tidy everything up properly
: ;LOC immediate
(;) 304 ?defn ; \ As local? is now false, everything else
\ gets tidied up by (;)
\ ============================================
: EVALUATE { addr len \ x1 x2 x3 x4 -- ?? }
save-input drop \ Must be 4
-> x4 -> x3 -> x2 -> x1 \ Move input-stream specs to locals
addr -> src-start len -> src-len 0 >in ! -1 -> source-id
echo? IF ." ***evaluating*** " addr len type cr THEN
interpret
x1 x2 x3 x4 4 restore-input ?error 25 ;
\ We can EVALUATE strings which might have embedded returns, and we can't
\ just convert returns to blanks since we want the comment operator \
\ to only skip to the end of the line, not the end of the string. We handle
\ this by defining an immediate "word" which just consists of a return, which
\ does nothing. We initially define it as X then patch it. Our dic
\ threading scheme doesn't clobber this since we just hash on the length,
\ which remains 1.
: X ; immediate
13 ( cr ) ' x >name 1+ c!
: (COMPINL) \ ( cfa -- )
2+ count evaluate ;
' (compinl) -> compinline
: INLINE{ immediate
method? IF -4 allot THEN \ Wipe out method entry sequence
\ %%% watch this on PPC!
inlMk w, & } ,str
align-dp
method? IF Mentry THEN \ Recompile method entry sequence
postpone ] ;
load class